package Day15.Demo09.Lock;

/**
 *解决线程安全问题的三种方案:使用Lock锁
 * java.utiL.concurrent.Locks.Lock接口
 * Lock实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作。
 * lock接口中的方法:
 *      void lock()获取锁。
 *      void unLock()释放锁。
 * java.util.concurrent.Locks.ReentrantLock implements lock接口
 * 使用步骤;
 * 1.在成员位置创建一个ReentrantLock对象
 * 2.在可能会出现安全问题的代码前调用Lock接口中的方法Lock获取锁
 * 3.在可能会出现安全问题的代码后调用Lock接口中的方法unLock释放锁
 */


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author hyhWTX
 * @version 1.0
 * @ClassName RunnableImpl
 * @date 2022年08月20日 16:05
 * @Description: 实现卖票案例
 */
public class RunnableImpl implements Runnable{
//    定义一个多线程共享的票源
    private  int ticket = 100;
//    1.在成员位置创建一个ReentrantLock对象
    Lock l = new ReentrantLock();
//   设置线程任务：卖票
    @Override
    public void run() {
//        使用死循环，让卖票操作重复执行！
        while (true){
//            2.在可能会出现安全问题的代码前调用Lock接口中的方法Lock获取锁
            l.lock();

//        先判断票是否存在
        if (ticket>0) {
//            提高安全问题出现的概率，让程序睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //票存在，卖票。ticket--
            System.out.println(Thread.currentThread().getName() + "--->正在卖票" + ticket + "张票");
            ticket--;
        }
//        3.在可能会出现安全问题的代码后调用Lock接口中的方法unLock释放锁
            l.unlock();
        }

    }
}
